﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Configuration.Install;
using System.IO;
using CI.Utils;

namespace CI.Misc
{
    /// <summary>
    /// Mesopotamia Installer
    /// </summary>
    [RunInstaller(true)]
    public partial class MesopotamiaInstaller : Installer
    {

        /// <summary>
        /// min required simulation files
        /// </summary>
        public readonly string[] RequiredFiles = new[] 
                                                     {                
                                                         "iRobotController.Y2009.M08.dll",
                                                         "iRobotController.Y2009.M08.pdb",
                                                         "iRobotController.Y2009.M08.Proxy.dll",
                                                         "iRobotController.Y2009.M08.Proxy.pdb",
                                                         "iRobotController.Y2009.M08.Transform.dll",
                                                         "iRobotController.Y2009.M08.Transform.pdb",
                                                         "MSRoboticsEnv.Y2008.M11.pdb",
                                                         "MSRoboticsEnv.Y2008.M11.dll",
                                                         "MSRoboticsEnv.Y2008.M11.Proxy.pdb",
                                                         "MSRoboticsEnv.Y2008.M11.Proxy.dll",
                                                         "MSRoboticsEnv.Y2008.M11.Transform.pdb",
                                                         "MSRoboticsEnv.Y2008.M11.Transform.dll",
                                                         "SimulatedDifferentialDrive.Y2009.M05.dll",
                                                         "SimulatedDifferentialDrive.Y2009.M05.pdb",
                                                         "SimulatedDifferentialDrive.Y2009.M05.Proxy.dll",
                                                         "SimulatedDifferentialDrive.Y2009.M05.Proxy.pdb",
                                                         "SimulatedDifferentialDrive.Y2009.M05.Transform.dll",
                                                         "SimulatedDifferentialDrive.Y2009.M05.Transform.pdb",
                                                         "SimulatedBumper.Y2009.M05.dll",
                                                         "SimulatedBumper.Y2009.M05.pdb",
                                                         "SimulatedBumper.Y2009.M05.Proxy.dll",
                                                         "SimulatedBumper.Y2009.M05.Proxy.pdb",
                                                         "SimulatedBumper.Y2009.M05.Transform.dll",
                                                         "SimulatedBumper.Y2009.M05.Transform.pdb",
                                                         "SimulatedWebcam.Y2010.M09.dll",
                                                         "SimulatedWebcam.Y2010.M09.pdb",
                                                         "SimulatedWebcam.Y2010.M09.Proxy.dll",
                                                         "SimulatedWebcam.Y2010.M09.Proxy.pdb",
                                                         "SimulatedWebcam.Y2010.M09.Transform.dll",
                                                         "SimulatedWebcam.Y2010.M09.Transform.pdb",
                                                         "InABox.Manifest.xml",
                                                         "InABox.xml",
                                                         "iRobotController.manifest.xml"
                                                     };

        private readonly SimEnv _simEnv = SimEnv.Instance;

        /// <summary>
        /// ctor
        /// </summary>
        public MesopotamiaInstaller()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Remove the old proxy's
        /// </summary>
        public void RemoveRoboticsProxys()
        {
            _simEnv.TraceLogger.LogDebug("RemoveRoboticsProxys - Start");
            try
            {
                var roboticsFolder = RoboticsConfig.FindRoboticsFolders();

                if (roboticsFolder != null)
                {
                    foreach (var file in RequiredFiles)
                    {
                        var filePath = Path.Combine(roboticsFolder, file);
                        // remove file
                        _simEnv.TraceLogger.LogDebug("Searching for file : " + filePath);
                        if (File.Exists(filePath))
                        {
                            _simEnv.TraceLogger.LogDebug("Deleteing file : " + filePath);
                            File.Delete(filePath);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _simEnv.TraceLogger.LogException("Error removing old proxy files", ex);
                throw;
            }
            _simEnv.TraceLogger.LogDebug("RemoveRoboticsProxys - Finish");

        }


        /// <summary>
        /// Checks for the proxy files and copies them over if they dont exist
        /// </summary>
        public void CopyRoboticsProxys(string sourceDir)
        {
            _simEnv.TraceLogger.LogDebug("CopyRoboticsProxys - Start");
            _simEnv.TraceLogger.LogDebug("Install Folder/Target Dir - " + sourceDir);

            try
            {
                var roboticsFolder = RoboticsConfig.FindRoboticsFolders();

                if (roboticsFolder != null)
                {
                    foreach (var file in RequiredFiles)
                    {
                        var sourceFile = file;
                        if (sourceFile.Contains(".xml"))
                        {
                            sourceFile = "XML\\" + sourceFile;
                        }
                        var targetFile = file;

                        var target = Path.Combine(roboticsFolder, targetFile);
                        var source = Path.Combine(sourceDir, sourceFile);

                        // copy the main proxy file
                        if (!File.Exists(target) && File.Exists(source))
                        {
                            _simEnv.TraceLogger.LogDebug(string.Format("Copying {0} to {1}", source, target));
                            File.Copy(source, target);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _simEnv.TraceLogger.LogException("CopyRoboticsProxys files", ex);
                throw;
            }

            _simEnv.TraceLogger.LogDebug("CopyRoboticsProxys - Finish");
        }

        /// <summary>
        /// On after install do the following tasks
        /// </summary>
        /// <param name="savedState"></param>
        protected override void OnAfterInstall(IDictionary savedState)
        {

            _simEnv.TraceLogger.LogDebug("MesopotamiaInstaller OnAfterInstall - Base");

            base.OnAfterInstall(savedState);

            _simEnv.TraceLogger.LogDebug("Cleaning old files from documents folder");
            CleanOldFiles();

            _simEnv.TraceLogger.LogDebug("MesopotamiaInstaller OnAfterInstall - RemoveRoboticsProxys");

            // remove any old robotics files
            RemoveRoboticsProxys();

            // remove an scenario files
            RoboticsConfig.DeleteScenarioFiles();
            _simEnv.TraceLogger.LogDebug("MesopotamiaInstaller OnAfterInstall - CopyRoboticsProxys");

            // copy new robotics files
            CopyRoboticsProxys(Context.Parameters["targetdir"]);

            _simEnv.TraceLogger.LogDebug("MesopotamiaInstaller OnAfterInstall - register httpreserve");

            // todo : register httpreserve
            var roboticsPath = RoboticsConfig.FindRoboticsFolders();
            var roboticsPort = 50000;
            var roboticsPortEnd = 50250;
            if (!string.IsNullOrEmpty(roboticsPath))
            {
                do
                {
                    var httpReserveProc = new System.Diagnostics.Process();
                    httpReserveProc.EnableRaisingEvents = false;
                    httpReserveProc.StartInfo.FileName = "HttpReserve.exe";
                    httpReserveProc.StartInfo.WorkingDirectory = roboticsPath;
                    httpReserveProc.StartInfo.Arguments = @" /port:" + roboticsPort + " /user:everyone /force";
                    httpReserveProc.StartInfo.CreateNoWindow = true;
                    httpReserveProc.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
                    httpReserveProc.Start();
                    httpReserveProc.WaitForExit();
                    roboticsPort += 2;
                } while (roboticsPort < roboticsPortEnd);
            }
        }

        /// <summary>
        /// purge old files from mesopotamia
        /// </summary>
        public void CleanOldFiles()
        {
            try
            {
                var documentsFolders = ResourceFolders.UsersResourceFolder();
                var files = Directory.GetFiles(documentsFolders, "*xml");

                foreach (var file in files)
                {
                    File.Delete(Path.Combine(documentsFolders, file));
                }
            }
            catch (Exception ex)
            {
                _simEnv.TraceLogger.LogException("Exception cleaning old files", ex);
            }

        }

        /// <summary>
        /// on after uninstall
        /// </summary>
        /// <param name="savedState"></param>
        protected override void OnAfterUninstall(IDictionary savedState)
        {
            base.OnAfterUninstall(savedState);

            // remove any robotics files left in their
            RemoveRoboticsProxys();

            // remove an scenario files
            RoboticsConfig.DeleteScenarioFiles();
        }

    }
}